//namespace scope
(function( DAS, $, undefined ){

		
var Utils = DAS.Utils = DAS.Utils || {};

//display error on page
Utils.error = function(msg) {
	$('#errors').add(
		$('<div class="errormsg">').html(msg)
	);
	return msg;
}
Utils.clearErrors = function() {
	$('#errors').empty();
}


/**
 * Log a message to console:
 *  either use jquery's console.error
 *  or a thrown exception.
 *  
 *  call initDevMode(); before use to activate
 *  use with:
 *      assert(<condition>, "message");
 *      eg: assert(1 != 1, "uh oh!");
 *  
 *  Log errors with:
 *       errorLog(message);
 *       eg: errorLog(xhr.status);
 */
 /*
assert = function(test, msg) { }
errorLog =function(msg) { }

initDevMode = function() {
    assert = function(test, msg) {
        msg = msg || "(no error message)";
        if(!test) {
            try {
                    throw Error();
                } catch(e) {
                    var foo = e;
                    var lines = e.stack.split('\n');
                    for(i in lines) {
                        if(i > 2) {
                        errorLog(msg + lines[i]);
                    }
                }
            }
        }
        throw("Assertion failed with: " + msg);
    };
    errorLog = function(msg) {
        if(typeof console.error == 'function') { 
            console.error(msg);
        } else {
            function errorLog(msg) {
                console.log("foo");
                setTimeout(function() {
                    throw new Error(msg);
                }, 0);
            }
        }
    };
}
*/




//array utils
Utils.inArray = function(val, arr) {
	for (var i=0; i<arr.length; i++) {
		if (arr[i] == val) return true;	
	}
	return false;
}
Utils.joinArray = function(val, arr) {
	for (var i=0; i<arr.length; i++) {
		if (arr[i] == val) return;
	}
	arr.push(val);
}

Utils.weedArray = function(weed, arr) {
	for (var i=arr.length-1; i>=0; i--) {
		if (arr[i] == weed) arr.splice(i,1);
	}
}

Utils.arrayDisect = function(arr, disectwith) {
	for (var weed, di=0; weed=disectwith[di]; di++) {
		for (var i=arr.length-1; i>=0; i--) {
			if (arr[i] == weed) arr.splice(i,1);
		}
	}
}
Utils.arrayIntersect = function(arr, intersectwith) {
	outerloop:
	for (var gem, di=0; gem=intersectwith[di]; di++) {
		for (var i=arr.length-1; i>=0; i--) {
			if (arr[i] == gem) continue outerloop;
		}
		arr.splice(i,1)
	}
}
Utils.arrayUnique = function(arr) {
	for (var i=arr.length-1; i>=1; i--) {
		var arri = arr[i];
		for (var j=i-1; j>=0; j--) {
			if (arr[j] == arri) {
				arr.splice(j,1)
				i--;
			}
		}
	}
}
Utils.objectKeys = function(obj) {
	var t = [];
	for (var k in obj)	t.push(k);	
	return t;
}

//splits string to object keys
Utils.splitToLookup = function(str, delimiter) {
	var lookup = {};
	var arr = str.split(delimiter);
	for (var i=0; i<arr.length; i++) {
		if (arr[i]) lookup[arr[i]] = true;
	}
	return lookup;
}




Utils.paddedNum = function(v, len) {
	var str = '0000000000'+parseInt(v);
	return 	str.slice(str.length-len);
}
//converts numerically listed keys to array [parent.basekey1, parent.basekey2, parent.basekey3]
//if maxnum is provided then it skips null values.. otherwise it quits on first null
Utils.keyListToTable = function(parent, basekey, maxnum) {
	var t = [], v;
	for (var i=1; (i<=maxnum) || !maxnum; i++) {
		if (v=parent[basekey+i]) {
			t.push( v );
			delete parent[basekey+i];
		}
		else if (!maxnum) break;
	}
	return t;
}

//merges values from one object onto another
Utils.merge = function(o, vals) {
	for (k in vals) o[k] = vals[k]; 
	return o;	
}
		


// Utils.sum = function() {
// 	var nt=0;
// 	for (var i=0; i<arguments.length; i++)
// 		nt += parseFloat(arguments[i] || '0');
// 	return String(nt);
// }
Utils.sum = function(n1,n2,_) {
	if (_) throw('too many sum args');
	return String(parseFloat(n1 || '0') + parseFloat(n2 || '0'));
}
Utils.negative = function(v) {
	return String(- parseFloat(v || '0'));
}
Utils.mult = function(n1,n2,_) {
	if (_) throw('too many mult args');
	return String(parseFloat(n1 || '1') * parseFloat(n2 || '1'));
}
Utils.normalise = function(v) {
	if (parseFloat(v || '0') <= 0) return '0';
	return v;
}
Utils.roundup = function(v) {
	return String( Math.ceil(parseFloat(v || '0')));
}


Utils.is = function(v) { return v && v!='0'; }



//derives a class from a baseclass. declare constructor inline. supports prototype chaining. eg:
Utils.Class = function(basecl, constr) {
	if (!constr) return basecl; //is baseclass. do nothing
	for (var k in basecl.prototype) 
		constr.prototype[k] = basecl.prototype[k]
//	constr.prototype.constructor = constr;
//	constr.prototype.prototype = basecl;
	constr.prototype.super = basecl;
	return constr;
}
//eg
//  var MyBase = Utils.Class(function(myarg){ 
//      this.id = myarg; 
//      
//      this.inlinefn = function(){console.log('yeah babby!')}
//  })
//  MyBase.prototype.myfn = function() {
//  	console.log(' my fn');
//  }
//  var MyDerived = Utils.Class(MyBase, function(myargs){ 
//      this.super.apply(this, arguments); //apply superclass constructor 
//  })
//  MyDerived.prototype.myotherfn = function() {
//  	console.log(' my other fn');
//  }
//  console.log(   (new MyDerived('hello')).id   );
//  new MyDerived().myotherfn();
//  new MyDerived().myfn();
//  new MyDerived().inlinefn();


/*
var g_controlState = {};
function deSerializeState(qs) {
	var pqs = new ParsedQueryString(qs);
	
	//set input values
	g_controlState = {};
	for (var k in pqs._parameters) {
		if (k!='mod' && k!='page' && k!='panes') {
			
			var v = pqs._parameters[k];
			//set input value
			try {
				//get element
				var $el = $('#'+k);
				var tag = $el.prop('tagName');
				
				//exists?
				if ($el.length) {
					//set element value
					if (tag == 'INPUT' && $el.attr('type') == 'checkbox')
						$el.prop('checked', v);
					else if (tag == 'SELECT')
						$el.prop('selectedIndex', v );
					else
						$el.val(v);
					
					g_controlState[k] = encodeURIComponent(v);
				}
			}
			catch(e) {console.log(e);}
		}
	}
	
	//open page
	var page = pqs.param('page') || 'item';
	var $btn = $('#'+page+'-page-button');
	if ($btn.length != 1)
		$btn = $('#item-page-button');
	$btn.trigger('click');
	
	//open panes
	var panes = pqs.param('panes');
	if (panes) PaneManager.deSerializePanes(panes);
}

//saves start of input element
$.fn.saveState = function() {
	this.each(function() {
		$el = $(this);
		var tag = $el.prop('tagName');
		var type = $el.attr('type');
		
		if ($el.attr('id') && (tag == 'INPUT' || tag =='SELECT' || tag == 'TEXTAREA')) {
			//read state
			var key = $el.attr('id'), val = $el.val();
			
			//read checkbox value
			if (tag == 'INPUT' && type == 'checkbox')
				val = $el.prop('checked') ? 1 : null;
			
			//ignore default option
			if (tag =='SELECT' && $el.find('option.default').val() == val)
				val = null;
			
			else if (tag =='SELECT')
				val = $el.prop('selectedIndex');
			
			//ignore blank text
			if (tag =='INPUT' && type == 'text' && val == '')
				val = null;
			//ignore blank text
			if (tag =='TEXTAREA' && val == '')
				val = null;
						
			//update local state
			if (val == null)
				delete g_controlState[key];
			else
				g_controlState[key] = encodeURIComponent(val);
		}
	});
	
	//trigger full save
	Utils.saveState();
	
	return this;
}
*/


////////////////////////////////////////////////////////////
// load dynamic content 
//   arguments; url, jQuery selector
//   loaded html will replace contents
//   content is cached (not suitable for dynamic content)
//   asyncronous (even for cached content) so works for a container that does not quite extst yet.
////////////////////////////////////////////////////////////

var g_contentCache = {}; 
Utils.loadContent = function(url, domsel) {
	//enclosed declarations
	var url = url;
	var domsel = domsel;
	var h_interval = null;
	
	//called on success
	function onLoadContent(txt) {
		g_contentCache[url] = txt;
		$(domsel).html(txt).hide().slideDown();
	}
	
	//check cache
	if (g_contentCache[url])
		setTimeout(function(){ onLoadContent(g_contentCache[url]) }, 10); //target may not exist yet
	else
		$.get(url, onLoadContent, 'text');
}
//mirrors loadContent visually but for known html (rather than a url to load)
//also asyncronous
Utils.insertContent = function(html, domsel) {
	setTimeout(function(){ $(domsel).html(html).hide().slideDown() }, 10);	//target may not exist yet
}


//namespace args
}( window.DAS = window.DAS || {}, jQuery ));

